package ftl.games.piratas;

import java.util.Arrays;
import java.util.Vector;

import javax.microedition.khronos.opengles.GL10;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.BoundCamera;
import org.anddev.andengine.engine.camera.ZoomCamera;
import org.anddev.andengine.engine.camera.hud.controls.AnalogOnScreenControl;
import org.anddev.andengine.engine.camera.hud.controls.AnalogOnScreenControl.IAnalogOnScreenControlListener;
import org.anddev.andengine.engine.camera.hud.controls.BaseOnScreenControl;
import org.anddev.andengine.engine.camera.hud.controls.BaseOnScreenControl.IOnScreenControlListener;
import org.anddev.andengine.engine.camera.hud.controls.DigitalOnScreenControl;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.IEntity;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXObject;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXObjectGroup;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXProperties;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXProperty;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTile;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTileProperty;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader.ITMXTilePropertiesListener;
import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException;
import org.anddev.andengine.entity.modifier.EntityModifier;
import org.anddev.andengine.entity.modifier.IEntityModifier;
import org.anddev.andengine.entity.modifier.LoopEntityModifier;
import org.anddev.andengine.entity.modifier.PathModifier;
import org.anddev.andengine.entity.modifier.IEntityModifier.IEntityModifierListener;
import org.anddev.andengine.entity.modifier.PathModifier.IPathModifierListener;
import org.anddev.andengine.entity.modifier.PathModifier.Path;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.util.FPSLogger;

import org.anddev.andengine.extension.physics.box2d.FixedStepPhysicsWorld;
import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.extension.physics.box2d.util.Vector2Pool;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.opengl.util.GLHelper;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.ArrayUtils;
import org.anddev.andengine.util.Debug;
import org.anddev.andengine.util.MathUtils;
import org.anddev.andengine.util.constants.Constants;
import org.anddev.andengine.util.modifier.IModifier;
import org.anddev.andengine.util.path.ITiledMap;
import org.anddev.andengine.util.path.astar.AStarPathFinder;



import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;

import ftl.games.piratas.Recorrido.Esquina;

import android.R.integer;
import android.content.Context;
import android.graphics.Point;
import android.opengl.GLU;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import android.widget.Toast;

public class PiratasActivity extends BaseGameActivity implements IOnSceneTouchListener{

	
	   
	 
	private static int CAMERA_WIDTH = 0;          
	private static int CAMERA_HEIGHT = 0;  
	
	private static float BARRIO_WIDTH = 0;
	private static float BARRIO_HEIGHT = 0;
	
	private static final int TILE_WIDTH = 32;
	
	private static final float mSpeed = (float) 0.3;
	
	private static final String TAG = "PiratasActivity";
	
	
	Display display;
	
	//private BoundCamera mCamera;
	private ZoomCamera mCamera;
	public Scene mScene;

	
	//Mapa
	private TMXTiledMap mapBarrioLevel1;
	
	private BitmapTextureAtlas mBitmapTextureAtlas;
	private BitmapTextureAtlas taCasa;
	
	//Casita
	private TiledTextureRegion trCasa;
	private Casa mCasa;
	
	
	
	//Camion
	private TiledTextureRegion trCamion;
	private Camion mCamion;
	
	private Body bodyCamion;
	
	//Joystik
	private BitmapTextureAtlas mOnScreenControlTexture;
	private TextureRegion mOnScreenControlBaseTextureRegion;
	private TextureRegion mOnScreenControlKnobTextureRegion;
	
	private PhysicsWorld mPhysicsWorld;
	
	public Vector<Casa> aCasas;
	public Casa mCasaPidiendo;
	public int iPosCasaPidiendo = 0;
	//public Vector<Casa> aaCasa = new Vector<Casa>();
	
	public Fabrica mFabrica; 
	
	private Toast toast;
	
	public int estado = EstadoLevel.CARGANDO;
	protected static Context mContext;
	
	public Rectangle rCamera;
	
	public Vector<CamionPirata> aPiratas;
	
	public Vector<Recorrido> aCaminos;
	
	private TMXLayer tmxLayer;
	
    private TMXTile tmxTile;
    
    private org.anddev.andengine.util.path.Path A_path;
    private AStarPathFinder<TMXLayer> finder;
    private float[] playerFootCordinates;
    private Path mCurrentPath;      
	private boolean isWalking;
	private int mWaypointIndex;
	private PathModifier mMoveModifier;
	private IEntityModifier mPathTemp;
	private String test;
	private int cCounter = 0;
	
	
	
	@Override
	public Engine onLoadEngine() {

		//Capturamos la pantalla por defecto
		WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
		display = wm.getDefaultDisplay();
 
		//Capturamos el ancho y alto de nuestra pantalla para configurar la camara
		CAMERA_WIDTH = display.getWidth();
		CAMERA_HEIGHT = display.getHeight();

		
		//this.mCamera = new BoundCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		this.mCamera = new ZoomCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT){
			//Forces the camera to move in integer steps. Helps prevent artifacts from appearing when scrolling
			@Override
			public void onApplySceneMatrix(GL10 pGL) {
				GLHelper.setProjectionIdentityMatrix(pGL);

				GLU.gluOrtho2D(pGL, (int) this.getMinX(), (int) this.getMaxX(), (int) this.getMaxY(),
						(int) this.getMinY());
				
				
			}
			
		};
		
		mContext = getApplicationContext();
		
		return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));

	}

	@Override
	public void onLoadResources() {
		this.toast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
		this.mBitmapTextureAtlas = new BitmapTextureAtlas(128, 64, TextureOptions.NEAREST);
		this.taCasa = new BitmapTextureAtlas(64, 32, TextureOptions.NEAREST);
		BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
		
		this.trCasa = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.taCasa, this, "house_tiled_1.png", 0, 0, 2, 1); // 32x32
		this.trCamion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "car.png", 0, 0,2,1); // 32x32

		
		this.mOnScreenControlTexture = new BitmapTextureAtlas(256, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mOnScreenControlBaseTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_base.png", 0, 0);
		this.mOnScreenControlKnobTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_knob.png", 128, 0);
		
		
		
		this.mEngine.getTextureManager().loadTextures(this.mBitmapTextureAtlas,mOnScreenControlTexture,this.taCasa);
		
		
	}

	@Override
	public Scene onLoadScene() {
		this.mEngine.registerUpdateHandler(new FPSLogger());

		this.mScene = new Scene();

		try {
			final TMXLoader tmxLoader = new TMXLoader(this, this.mEngine.getTextureManager(), TextureOptions.NEAREST, new ITMXTilePropertiesListener() {
				@Override
				public void onTMXTileWithPropertiesCreated(final TMXTiledMap pTMXTiledMap, final TMXLayer pTMXLayer, final TMXTile pTMXTile, final TMXProperties<TMXTileProperty> pTMXTileProperties) {
				}
			});
			
			
			
			this.mapBarrioLevel1 = tmxLoader.loadFromAsset(this, "tmx/map0.tmx");
			
            final ITiledMap<TMXLayer> tmap = new ITiledMap<TMXLayer>()
            {
            	 

				// Pretty self explanatory
                @Override
                public int getTileColumns() {
                        return mapBarrioLevel1.getTileColumns();
                }
               
                // Pretty self explanatory
                @Override
                public int getTileRows()
                {
                        return mapBarrioLevel1.getTileRows();
                }
               
                // Lets you customize what blocks you want to be considered blocked
                @Override
                public boolean isTileBlocked(TMXLayer pTile, final int pToTileColumn, final int pToTileRow)
                {   
                	TMXTile tt = mapBarrioLevel1.getTMXLayers().get(0).getTMXTile(pToTileColumn, pToTileRow);
                    int i= tt.getGlobalTileID();
                    Log.d(Constantes.LOG_POSICION_CAMION, String.valueOf(i));
                    return false;
                	
                    
                }
               
                // This is the key function to understand for AStar pathing
                // Returns the cost of the next tile in the path
                @Override
                public float getStepCost(final TMXLayer pTile, final int pFromTileColumn, final int pFromTileRow, final int pToTileColumn, final int pToTileRow)
                {		
                	//I coded this it because it caused more problems than it was worth, but this is where the path value is decided
                		
                        //grab the first property from a tile at pToTileColumn x pToTileRow
                        //TMXProperty cost = tmxLayer.getTMXTile(pToTileColumn, pToTileRow).getTMXTileProperties(mapBarrioLevel1).get(0);
                        //Gets the value of the string
                        //return Float.parseFloat(cost.getValue());
                	return 0;
                       
                }
               
                // If the tile is processed by findpath(), any extra code you might want goes here
                @Override
                public void onTileVisitedByPathFinder(int pTileColumn, int pTileRow) {
                        // Do Nothing
                }
            };
            // Add the non-object layers to the scene
			
    		tmxLayer = this.mapBarrioLevel1.getTMXLayers().get(0);
    		this.mScene.attachChild(tmxLayer);
    		finder = new AStarPathFinder<TMXLayer>(tmap, 30, false);			
			
			
		} catch (final TMXLoadException tmxle) {
			Debug.e(tmxle);
		}


		
		
		BARRIO_WIDTH = tmxLayer.getWidth();
		BARRIO_HEIGHT = tmxLayer.getHeight();
		
		Log.d(Constantes.LOG_DIMENSIONES, "Pantalla {w:"+CAMERA_WIDTH+", h: "+CAMERA_HEIGHT+"}");
		Log.d(Constantes.LOG_DIMENSIONES, "Barrio {w:"+BARRIO_WIDTH+", h: "+BARRIO_HEIGHT+"}");
		
		
		
		/* Make the camera not exceed the bounds of the TMXEntity. */
		this.mCamera.setBounds(0, BARRIO_WIDTH, 0, BARRIO_HEIGHT);
		this.mCamera.setBoundsEnabled(true);


		
		
		this.mPhysicsWorld = new FixedStepPhysicsWorld(50, new Vector2(0, 0), false, 8, 1);		
		
		this.mScene.setOnSceneTouchListener(this);
		
		//cargarFisicaBarrio();
		this.createUnwalkableObjects(this.mapBarrioLevel1);
		this.cargarFisicaBarrio();
		this.initCamion();
		this.initOnScreenControls();	
		this.asignarCaminosAPiratas();
		
		
		this.mScene.registerUpdateHandler(this.mPhysicsWorld);
		
        final Rectangle currentTileRectangle = new Rectangle(this.mCamion.getX(), this.mCamion.getY(), this.mapBarrioLevel1.getTileWidth(), this.mapBarrioLevel1.getTileHeight());
        currentTileRectangle.setColor(1, 0, 0, 0.25f);
        this.mScene.getLastChild().attachChild(currentTileRectangle);

		this.mScene.registerUpdateHandler(new IUpdateHandler() {
			@Override
			public void reset() { }

			@Override
			public void onUpdate(final float pSecondsElapsed) {
				
				Camion camion = PiratasActivity.this.mCamion;
				
            	/* Get the scene-coordinates of the tile center.*/
            	playerFootCordinates = camion.convertLocalToSceneCoordinates(32, 32);

                /* Get the tile where the center of the current tile is. */
                tmxTile = tmxLayer.getTMXTileAt(playerFootCordinates[Constants.VERTEX_INDEX_X],
                	playerFootCordinates[Constants.VERTEX_INDEX_Y]);
                if(tmxTile != null) {
                    // tmxTile.setTextureRegion(null); <-- Rubber-style removing of tiles =D
                    currentTileRectangle.setPosition(tmxTile.getTileX(), tmxTile.getTileY());
                }				
				
                walkTo(camion.getX(), camion.getY(), PiratasActivity.this.mScene);
                
				if (PiratasActivity.this.estado == EstadoLevel.INICIADO)
				{
					
					switch (camion.estado)
					{
						case EstadoCamion.EN_PUESTO:

							if ( PiratasActivity.this.aCasas != null && (PiratasActivity.this.iPosCasaPidiendo < PiratasActivity.this.aCasas.size()) )
							{
								PiratasActivity.this.mCasaPidiendo = PiratasActivity.this.aCasas.get(PiratasActivity.this.iPosCasaPidiendo);
								PiratasActivity.this.mCasaPidiendo.Pedir();
								
								PiratasActivity.this.mCamera.setChaseEntity(PiratasActivity.this.rCamera);
								
								PiratasActivity.this.mCamera.setZoomFactor(2.0f);
								final Path path = new Path(3).to(PiratasActivity.this.mFabrica.getX(), PiratasActivity.this.mFabrica.getY()).to(PiratasActivity.this.mCasaPidiendo.getX(), PiratasActivity.this.mCasaPidiendo.getY()).to(PiratasActivity.this.mFabrica.getX(), PiratasActivity.this.mFabrica.getY());
								PiratasActivity.this.rCamera.registerEntityModifier(new PathModifier(2, path,null, new IPathModifierListener(){

									@Override
									public void onPathStarted(
											PathModifier pPathModifier,
											IEntity pEntity) {
										// TODO Auto-generated method stub
										
									}

									@Override
									public void onPathWaypointStarted(
											PathModifier pPathModifier,
											IEntity pEntity, int pWaypointIndex) {
										// TODO Auto-generated method stub
										
									}

									@Override
									public void onPathWaypointFinished(
											PathModifier pPathModifier,
											IEntity pEntity, int pWaypointIndex) {
										// TODO Auto-generated method stub
										
									}

									@Override
									public void onPathFinished(
											PathModifier pPathModifier,
											IEntity pEntity) {
										// TODO Auto-generated method stub
										PiratasActivity.this.mCamera.setZoomFactor(1f);
										
										PiratasActivity.this.mCamera.setChaseEntity(null);
										PiratasActivity.this.mCamion.estado = EstadoCamion.ENTREGANDO;
									}}));
								
								//PiratasActivity.this.mCamera.setChaseEntity(camion);
								
								
								//PiratasActivity.this.mCamera.setChaseEntity(mCasaPidiendo);
								//PiratasActivity.this.mCasaPidiendo.getX(), PiratasActivity.this.mCasaPidiendo.getY()
								//PiratasActivity.this.mCamera.setCenter(PiratasActivity.this.mCasaPidiendo.getX(), PiratasActivity.this.mCasaPidiendo.getY());
								
							}
							break;
						
						case EstadoCamion.ENTREGANDO:
							
							//Log.d(Constantes.LOG_POSICION_CAMION, "Scroll {x:"+camion.getX()+", y: "+camion.getY()+"}");
							
							
							
							if (PiratasActivity.this.mCasaPidiendo.EstaElCamionEnLaPuerta(camion))
							{
								PiratasActivity.this.mCasaPidiendo.Recibir();
								camion.estado = EstadoCamion.VOLVIENDO;
							}
							
							break;
							
						case EstadoCamion.VOLVIENDO:
							if (PiratasActivity.this.mFabrica.EstaElCamionEnLaPuerta(camion))
							{
								PiratasActivity.this.iPosCasaPidiendo++;
								camion.estado = EstadoCamion.EN_PUESTO;
							}
							
							
							
							break;
					}
					
					
					
				}
				
			}
		});

		this.estado = EstadoLevel.INICIADO;
		
		return this.mScene;

	}

	@Override
	public void onLoadComplete() {
		// TODO Auto-generated method stub
		
	}

	
	private void initCamion()
	{

		//Buscamos el centro de la pantalla
		final int centerX = (int) (this.mFabrica.getCoordenadasPuerta()[0]);                  
		final int centerY = (int) (this.mFabrica.getCoordenadasPuerta()[2]);

 
		/* Create the sprite and add it to the scene. */
		this.mCamion = new Camion(centerX, centerY,25,25, this.trCamion);
		this.mCamion.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

		//this.mCamera.setZoomFactor(2);
		//this.mCamera.setChaseEntity(mCamion);
		

		final FixtureDef boxFixtureDef = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
		this.bodyCamion = PhysicsFactory.createBoxBody(this.mPhysicsWorld, this.mCamion, BodyType.DynamicBody, boxFixtureDef);
		
		this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(this.mCamion, this.bodyCamion, true, false));
		
		
		this.mScene.attachChild(this.mCamion);
	
		
	}
	
	private void initOnScreenControls() {
		final DigitalOnScreenControl analogOnScreenControl = new DigitalOnScreenControl(0, CAMERA_HEIGHT - this.mOnScreenControlBaseTextureRegion.getHeight(), this.mCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, new IOnScreenControlListener() {
			@Override
			public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
				
					
					final Body bodyCamionAux = PiratasActivity.this.bodyCamion;
					
					if (PiratasActivity.this.mCamion.estado != EstadoCamion.EN_PUESTO ){
						
						
						if (pValueX != 0 || pValueY != 0 ){
							
						final Vector2 velocity = Vector2Pool.obtain((int)pValueX*5, (int)pValueY*5);
						bodyCamionAux.setLinearVelocity(velocity);
						Vector2Pool.recycle(velocity);
						
						final float rotationInRad = (float)Math.atan2(-(int)pValueX, (int)pValueY);
						bodyCamionAux.setTransform(bodyCamionAux.getWorldCenter(), rotationInRad);
						
		
						PiratasActivity.this.mCamion.setRotation(MathUtils.radToDeg(rotationInRad));
						}
					}
					else
					{
						bodyCamionAux.setLinearVelocity(0,0);
					}
					
			}

			//@Override
			public void onControlClick(AnalogOnScreenControl pAnalogOnScreenControl) {
				// TODO Auto-generated method stub
				
			}


		});

		analogOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		analogOnScreenControl.getControlBase().setAlpha(0.5f);
		analogOnScreenControl.getControlKnob().setAlpha(0.5f);
		analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
		analogOnScreenControl.getControlBase().setScale(1.5f);
		analogOnScreenControl.getControlKnob().setScale(1.5f);
		analogOnScreenControl.refreshControlKnobPosition();

		this.mScene.setChildScene(analogOnScreenControl);
	}

	private void cargarFisicaBarrio()
	{
		final Shape ground = new Rectangle(0, BARRIO_HEIGHT - 2, BARRIO_WIDTH, 2);
		final Shape roof = new Rectangle(0, 0, BARRIO_WIDTH, 2);
		final Shape left = new Rectangle(0, 0, 2, BARRIO_HEIGHT);
		final Shape right = new Rectangle(BARRIO_WIDTH - 2, 0, 2, BARRIO_HEIGHT);

		
		final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f);
		PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallFixtureDef);
		PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallFixtureDef);
		PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
		PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);

		this.mScene.attachChild(ground);
		this.mScene.attachChild(roof);
		this.mScene.attachChild(left);
		this.mScene.attachChild(right);

	}
	
	
	@Override
	public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
		Log.d(Constantes.LOG_TOUCH, "Scroll {x:"+pSceneTouchEvent.getX()+", y: "+pSceneTouchEvent.getY()+"}");
		return false;
	}		
	
	private void createUnwalkableObjects(TMXTiledMap map){ 
		final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
		TiledTextureRegion trCasaClone;
		float[] coord; 
		Rectangle rect;
		Casa oCasa;
		CamionPirata oPirata;
		
		int iCasas = 0;
		 
		Path caminoPirata;
		
		// Loop through the object groups 
		for(final TMXObjectGroup group: map.getTMXObjectGroups()) { 
			if(group.getName().equals("Barrios")){ 
			// This is our "wall" layer. Create the boxes from it 
				for(final TMXObject object : group.getTMXObjects()) { 
					rect = new Rectangle(object.getX(), object.getY(),object.getWidth(), object.getHeight()); 
					rect.setAlpha(0);
					PhysicsFactory.createBoxBody(this.mPhysicsWorld, rect, BodyType.StaticBody, wallFixtureDef);
					this.mScene.attachChild(rect); 
				} 
			} 
			if(group.getName().equals("Piratas")){ 
				this.aPiratas = new Vector<CamionPirata>();
				// This is our "wall" layer. Create the boxes from it 
					for(final TMXObject object : group.getTMXObjects()) { 
						oPirata = new CamionPirata(object.getX(), object.getY(),32, 32, this.trCamion.clone());
						this.aPiratas.add(oPirata);
						this.mScene.attachChild(oPirata); 
					} 
				}
			if(group.getName().equals("CaminoPirata")){ 
					this.aCaminos = new Vector<Recorrido>();
					caminoPirata = new Path(Integer.parseInt(group.getTMXObjects().get(0).getTMXObjectProperties().get(1).getValue())+1);
					//caminoPirata.to((group.getTMXObjects().get(0).getWidth()/2) + group.getTMXObjects().get(0).getX(), (group.getTMXObjects().get(0).getHeight()/2) + group.getTMXObjects().get(0).getY());
					int nroCaminoActual = Integer.parseInt(group.getTMXObjects().get(0).getTMXObjectProperties().get(0).getValue());
					int[]a = new int[4];
					
					for(TMXObject object : group.getTMXObjects()) { 
						
						if (nroCaminoActual != Integer.parseInt(object.getTMXObjectProperties().get(0).getValue()) )
						{
							//Es un nuevo camino. guardo el path y genero uno nuevo.
							caminoPirata.to(caminoPirata.getCoordinatesX()[0],caminoPirata.getCoordinatesY()[0]);
							this.aCaminos.add(new Recorrido(caminoPirata));
							
							caminoPirata = new Path(Integer.parseInt(object.getTMXObjectProperties().get(1).getValue())+1);
							caminoPirata.to(object.getX(), object.getY());
							nroCaminoActual = Integer.parseInt(object.getTMXObjectProperties().get(0).getValue());
							
						}else
						{
							caminoPirata.to(object.getX(), object.getY());
							
						}
					}
					caminoPirata.to(caminoPirata.getCoordinatesX()[0],caminoPirata.getCoordinatesY()[0]);
					this.aCaminos.add(new Recorrido(caminoPirata));
					
				}			
			if(group.getName().equals("Casas")){ 
				this.aCasas = new Vector<Casa>();
				// This is our "wall" layer. Create the boxes from it 
					for(final TMXObject object : group.getTMXObjects()) { 
						
						trCasaClone = this.trCasa.clone();
						oCasa = new Casa(object.getX(), object.getY(),object.getWidth(), object.getHeight(), trCasaClone);
						oCasa.setPosPuerta(object.getTMXObjectProperties().get(0).getValue());
						oCasa.setPosPuerta(object.getTMXObjectProperties().get(0).getValue());
						//coord = this.aCasas[iCasas].getCoordenadasPuerta();
						//rect = new Rectangle(coord[0], coord[2], this.aCasas[iCasas].getWidth(), this.aCasas[iCasas].getHeight());
						this.aCasas.add(oCasa);
						this.mScene.attachChild(oCasa);
						//this.mScene.attachChild(this.aCasas[iCasas]);
						//this.mScene.attachChild(rect);
						iCasas++;
					} 
				}
			if(group.getName().equals("Fabrica")){ 
				// This is our "wall" layer. Create the boxes from it 
					for(final TMXObject object : group.getTMXObjects()) { 
						
						trCasaClone = this.trCasa.clone();
						this.mFabrica = new Fabrica(object.getX(), object.getY(),object.getWidth(), object.getHeight(), trCasaClone);
						this.mFabrica.setPosPuerta(object.getTMXObjectProperties().get(0).getValue());
						coord = this.mFabrica.getCoordenadasPuerta();
						rect = new Rectangle(coord[0], coord[2], this.mFabrica.getWidth(), this.mFabrica.getHeight());
						this.rCamera = new Rectangle(object.getX(), object.getY(), 1, 1);
						this.rCamera.setAlpha(0);
						this.mScene.attachChild(this.rCamera);
						this.mScene.attachChild(this.mFabrica);
						this.mScene.attachChild(rect);
					} 
				} 
			
		}
		
	} 
	public void asignarCaminosAPiratas()
	{
		CamionPirata oPirata;
		int iCantCaminos = 0;
		int iEsquina = -1;
		
		Esquina oEsquina;
		if (this.aCaminos != null)
		{
			
			iCantCaminos = this.aCaminos.size() ;
			this.aPiratas = new Vector<CamionPirata>();
			for(int i=0; i<iCantCaminos; i++)
			{
				for (int j=0; j<2; j++){
					oEsquina = this.aCaminos.get(i).getEsquina(j);
					oPirata = new CamionPirata(oEsquina.x, oEsquina.y,30, 30, this.trCamion.clone());
					//oPirata.registerEntityModifier(new LoopEntityModifier(new PathModifier(10, this.aCaminos.get(i).generarPathDesdeEsquina(oEsquina.index))) );
					
					this.aPiratas.add(oPirata);
					
					this.mScene.attachChild(oPirata);
				}
			}
		}
	}
    // ===========================================================
    // Methods
    // ===========================================================
    
    //This method controls the path the sprite will take once a location is passed into it
    public void walkTo(final float pX, final float pY, Scene pScene){
    	
        //Puts the touch events into an array
        final float[] pToTiles = pScene.convertLocalToSceneCoordinates(pX, pY);
     
        //Gets the tile at the touched location
        final TMXTile tmxTilePlayerTo =  tmxLayer.getTMXTileAt(
               pToTiles[Constants.VERTEX_INDEX_X],
               pToTiles[Constants.VERTEX_INDEX_Y]
        );
                       
    /*********/ //if is walking and there is a A_path ******************
        if (isWalking == true && A_path != null) {
        	//Calls the Walk to next waypoint method,
    		//First & Second Param: are the touched x and y position 
    		//Third Param: is the scene
            walkToNextWayPoint(pX,pY,pScene);
        }
                   
        else if (A_path == null ) {                
            // Create the path with findPath()
            // First Param: TMXLayer in this case, templated through the above ITiledMap and AStarPathFinder functions
            // Second Param: Max Cost of a complete path, NOT A SINGLE TILE! - if value is too low your program will crash
            // Third & Fourth Param: From Column and From Row - Starting tile location
            // Fifth & Sixth Param: To Column and To Row - Ending tile location            	
            A_path = finder.findPath(tmxLayer,100,
                 //Sprite's initial tile location
                 tmxTile.getTileColumn(),
                 tmxTile.getTileRow(),
                 //Sprite's final tile location
                 tmxTilePlayerTo.getTileColumn(),
                 tmxTilePlayerTo.getTileRow());
     
            //Calls the Load path method
            loadPathFound();
        }
    }
    //If the sprite is moving and the screen is touched then this method will be called.
    //It creates a sub path that creates a smooth transition to the center of a tile before rerouting
    private void walkToNextWayPoint(final float pX, final float pY, final Scene pScene) {
    	//Unregisters the current paths
    	
    	this.aPiratas.get(0).unregisterEntityModifier(mMoveModifier);
    	this.aPiratas.get(0).unregisterEntityModifier(mPathTemp); //mPathTemp is another global PathModifier
        
        //Creates a copy of the path currently being walked
        final Path lPath = mCurrentPath.clone();
        
        //create a new path with length 2 from current sprite position to next original path waypoint
        final Path path = new Path(2);
        //Continues the path for one more tile 
        path
            .to(this.aPiratas.get(0).getX(), this.aPiratas.get(0).getY())
            //.to(lPath.getCoordinatesX()[mWaypointIndex+1], lPath.getCoordinatesY()[mWaypointIndex+1]);}
            .to(this.mCamion.getX(), this.mCamion.getY());
        
        //recalculate the speed. TILE_WIDTH is the tmx tile width, use yours
        float lSpeed = path.getLength() * mSpeed / (TILE_WIDTH); 
                   
        //Create the modifier of this subpath
        mPathTemp = new PathModifier(lSpeed, path, new IEntityModifierListener() {
                           
            public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem) {
                                   
            }
                           
            public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem) {
                           
            }
        }, new IPathModifierListener() {
                           
            public void onPathWaypointStarted(final PathModifier pPathModifier, final IEntity pEntity,  int pWaypointIndex) {
            	                   
        }
            
            public void onPathWaypointFinished(PathModifier pPathModifier, IEntity pEntity,
                int pWaypointIndex) {
                                   
            }
                           
            public void onPathStarted(PathModifier pPathModifier, IEntity pEntity) {
     
            }
                           
            public void onPathFinished(PathModifier pPathModifier, IEntity pEntity) {
            		//Once the subpath is finished the a new one is created at the new touched location
                    A_path = null;
                    walkTo(pX, pY,pScene);
                    //Stops the animation of the player once it stops
                    //player.stopAnimation();
            }
        });
        //Registers the newly created path modifier           
        this.aPiratas.get(0).registerEntityModifier(mPathTemp);          
    }
    
    //Creates the A* Path and executes it
    private void loadPathFound() {
    	   
        if (A_path != null) {
            //Global var
            mCurrentPath = new Path(A_path.getLength());
            int tilewidth = mapBarrioLevel1.getTileWidth();
            int tileheight = mapBarrioLevel1.getTileHeight();
                                   
            for(int i = 0; i < A_path.getLength(); i++){
                mCurrentPath.to(A_path.getTileColumn(i) * tilewidth, A_path.getTileRow(i) * tileheight);
            }
            doPath();
        }
    }
    //Creates the modifier for the A*Path
    private void doPath() {
    	 
        //Create this mMoveModifier as Global, there is mSpeed  too -> player speed
        mMoveModifier = new PathModifier(mSpeed * A_path.getLength(), mCurrentPath, new IEntityModifierListener() {
     
            public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem) {
     
            }
           
            public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem) {
     
            }
        }, new PathModifier.IPathModifierListener() {


			public void onPathWaypointStarted(final PathModifier pPathModifier, final IEntity pEntity,  int pWaypointIndex) {
				 
                //Character animation are controlled here
//                switch(A_path.getDirectionToNextStep(pWaypointIndex)) {
//                case DOWN:
//                        player.animate(new long[]{200, 200, 200}, 6, 8, true);
//                        break;
//                case RIGHT :
//                        player.animate(new long[]{200, 200, 200}, 3, 5, true);
//                        break;
//                case UP:
//                        player.animate(new long[]{200, 200, 200}, 0, 2, true);
//                        break;
//                case LEFT:
//                        player.animate(new long[]{200, 200, 200}, 9, 11, true);
//                        break;
//                default:
//                        break;
//                }            
                           
                //Keep the waypointIndex in a Global Var
                mWaypointIndex = pWaypointIndex;
           
            }
                           
            public void onPathWaypointFinished(PathModifier pPathModifier, IEntity pEntity,
                    int pWaypointIndex) {
           
            }
                                   
            public void onPathStarted(PathModifier pPathModifier, IEntity pEntity) {
     
                //Set a global var
                isWalking = true;
            }
                                   
            public void onPathFinished(PathModifier pPathModifier, IEntity pEntity) {
     
                //Stop walking and set A_path to null
                isWalking = false;
                A_path = null;
                //player.stopAnimation();
            }
     
        });
     
        this.aPiratas.get(0).registerEntityModifier(mMoveModifier);
    }

    

    // ===========================================================
    // Inner and Anonymous Classes
    // ===========================================================
	
	
	
}